﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using WebChatApi.Common.Interface;

namespace WebChatApi.Common
{
    /// <summary>
    /// Class for service account.
    /// </summary>

    public class ServiceAccount : IIdentifiable
    {
        /// <summary>
        /// String format to generate string account.
        /// {0}: User
        /// {1}: Password
        /// {2}: Domain, server name, Ip, or any identity
        /// {3}: Token
        /// </summary>
        protected const string stringAccountFormat = "{0}:{1}@{2}#{3}";

        #region Properties

        /// <summary>
        /// Gets or sets the key.
        /// </summary>
        /// <value>
        /// The key.
        /// </value>
        public Guid Key
        {
            get;
            protected set;
        }


        /// <summary>
        /// Gets or sets the service identity.
        /// </summary>
        /// <value>
        /// The service identity.
        /// </value>
        public string ServiceIdentity
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the login identity.
        /// </summary>
        /// <value>
        /// The login identity.
        /// </value>
        public string LoginIdentity
        {
            get;
            protected set;
        }

        /// <summary>
        /// Gets or sets the login password.
        /// </summary>
        /// <value>
        /// The login password.
        /// </value>
        public string LoginPassword
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the token info.
        /// </summary>
        /// <value>
        /// The token info.
        /// </value>
        public string TokenInfo
        {
            get;
            set;
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceAccount" /> class.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="serviceIdentity">The service identity.</param>
        /// <param name="loginIdentity">The login identity.</param>
        /// <param name="loginPassword">The login password.</param>
        /// <param name="tokenInfo">The token info.</param>
        public ServiceAccount(Guid key, string serviceIdentity = null, string loginIdentity = null, string loginPassword = null, string tokenInfo = null)
        {
            this.Key = key;
            this.ServiceIdentity = serviceIdentity;
            this.LoginIdentity = loginIdentity;
            this.LoginPassword = loginPassword;
            this.TokenInfo = tokenInfo;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceAccount"/> class.
        /// </summary>
        /// <param name="serviceIdentity">The service identity.</param>
        /// <param name="SignInIdentity">The SignIn identity.</param>
        /// <param name="SignInPassword">The SignIn password.</param>
        /// <param name="tokenInfo">The token info.</param>
        public ServiceAccount(string serviceIdentity = null, string SignInIdentity = null, string SignInPassword = null, string tokenInfo = null)
            : this(Guid.NewGuid(), serviceIdentity, SignInIdentity, SignInPassword, tokenInfo)
        {
        }

        #endregion

        ///// <summary>
        ///// Gets the password.
        ///// </summary>
        ///// <returns></returns>
        //protected string GetPassword()
        //{
        //    return this.LoginPassword;
        //}

        ///// <summary>
        ///// Gets the token.
        ///// </summary>
        ///// <returns></returns>
        //protected string GetToken()
        //{
        //    return this.TokenInfo;
        //}

        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String" /> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return string.Format(stringAccountFormat,
               this.GetStringValue(this.LoginIdentity),
               this.GetStringValue(this.LoginPassword),
               this.GetStringValue(this.ServiceIdentity),
               this.GetStringValue(this.TokenInfo));
        }

        /// <summary>
        /// Splits the string account.
        /// </summary>
        /// <param name="accountString">The account string.</param>
        /// <returns></returns>
        /// <exception cref="InvalidObjectException">accountString;null</exception>
        protected static string[] SplitStringAccount(string accountString)
        {
            string[] result = new string[4];
            result.CheckNullObject(accountString, "accountString");

            string[] parts = accountString.Split('@');
            if (parts.Length > 1)
            {
                string[] SignInParts = parts[0].Split(':');
                if (SignInParts.Length > 0)
                {
                    result[0] = SignInParts[0];
                }
                if (SignInParts.Length > 1)
                {
                    result[1] = SignInParts[1];
                }

                string[] serviceParts = parts[1].Split('#');
                if (serviceParts.Length > 0)
                {
                    result[2] = serviceParts[0];
                }
                if (serviceParts.Length > 1)
                {
                    result[3] = serviceParts[1];
                }
            }
            else
            {
                throw new InvalidObjectException("accountString", null, accountString);
            }

            return result;
        }

        /// <summary>
        /// Loads the service account from string.
        /// </summary>
        /// <param name="stringAccount">The string account.</param>
        /// <returns></returns>
        public static ServiceAccount LoadServiceAccountFromString(string stringAccount)
        {
            string[] parts = SplitStringAccount(stringAccount);

            ServiceAccount result = new ServiceAccount();
            result.LoginIdentity = parts[0];
            result.LoginPassword = parts[1];
            result.ServiceIdentity = parts[2];
            result.TokenInfo = parts[3];

            return result;
        }
    }
}
